﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.Paint.Mesh.CApMeshManager
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EngineeringInternalExtension;
using EngineeringInternalExtension.DataTypes;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.PrivateImplementationDetails;


namespace DnProcessSimulateCommands.Paint.Mesh;

public class CApMeshManager : INotifyPropertyChanged, INotifyCollectionChanged, IDisposable
{
  public static double DEVIATION_DEFAULT_VALUE = 0.5;
  public static double DISTANCE_DEFAULT_VALUE = 100.0;
  public static double ANGLE_DEFAULT_VALUE = Math.PI / 12.0;
  private TxColor m_emphasizeColor = new TxColor(TxColor.TxColorGray);
  private TxObjectList m_previewMeshList = new TxObjectList();
  private TxObjectList<TxMeshComponent> m_blankMeshesWithCoverage = new TxObjectList<TxMeshComponent>();
  private TxObjectList m_selectedParts;
  private string _message;
  private MessageTypes m_messageType;
  private bool m_isDataReady;
  private bool m_meshIsCreating;
  private bool m_newMeshCreated;
  private double m_deviation = CApMeshManager.DEVIATION_DEFAULT_VALUE;
  private double m_distance = CApMeshManager.DISTANCE_DEFAULT_VALUE;
  private double m_angle = CApMeshManager.ANGLE_DEFAULT_VALUE;
  private TxComponent m_component;
  private string m_errorMessage;
  private MessageTypes m_errorMessageType;
  private bool m_disposed;

  public CApMeshManager(TxObjectList selectedObjects)
  {
    this.LinearUnitName = TxApplication.Options.Units.LinearUnitName;
    this.AngularUnitName = TxApplication.Options.Units.AngularUnitName;
    this.m_emphasizeColor.Transparency = 0.3;
    if (selectedObjects != null)
      this.m_selectedParts = selectedObjects;
    else
      this.m_selectedParts = new TxObjectList();
  }

  ~CApMeshManager() => this.Dispose(false);

  public void Dispose()
  {
    this.Dispose(true);
    GC.SuppressFinalize((object) this);
  }

  protected virtual void Dispose(bool disposing)
  {
    if (this.m_disposed)
      return;
    int num = disposing ? 1 : 0;
    this.DestroyComponent(ref this.m_component);
    this.m_disposed = true;
  }

  public string LinearUnitName { get; set; }

  public string AngularUnitName { get; set; }

  public bool IsDataReady
  {
    get => this.m_isDataReady;
    private set
    {
      this.m_isDataReady = value;
      this.OnPropertyChanged(nameof (IsDataReady));
    }
  }

  public bool MeshIsCreating
  {
    get => this.m_meshIsCreating;
    set
    {
      this.m_meshIsCreating = value;
      this.OnPropertyChanged(nameof (MeshIsCreating));
    }
  }

  public bool NewMeshCreated
  {
    get => this.m_newMeshCreated;
    set => this.m_newMeshCreated = value;
  }

  public string Message
  {
    get => this._message;
    internal set
    {
      this._message = value;
      this.OnPropertyChanged(nameof (Message));
    }
  }

  public MessageTypes MessageType
  {
    get => this.m_messageType;
    set
    {
      this.m_messageType = value;
      this.OnPropertyChanged(nameof (MessageType));
    }
  }

  public TxObjectList SelectedParts
  {
    get => this.m_selectedParts;
    set
    {
      this.m_selectedParts = value;
      this.OnPropertyChanged(nameof (SelectedParts));
      this.ValidateIsDataReady();
    }
  }

  public double Deviation
  {
    get => this.m_deviation;
    set
    {
      this.m_deviation = value;
      this.OnPropertyChanged(nameof (Deviation));
    }
  }

  public double Distance
  {
    get => this.m_distance;
    set
    {
      this.m_distance = value;
      this.OnPropertyChanged(nameof (Distance));
    }
  }

  public double Angle
  {
    get => this.m_angle;
    set
    {
      this.m_angle = value;
      this.OnPropertyChanged(nameof (Angle));
    }
  }

  public TxComponent Component => this.m_component;

  public event PropertyChangedEventHandler PropertyChanged;

  protected virtual void OnPropertyChanged(string propertyName)
  {
    if (this.PropertyChanged == null)
      return;
    this.PropertyChanged((object) this, new PropertyChangedEventArgs(propertyName));
  }

  public event NotifyCollectionChangedEventHandler CollectionChanged;

  protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
  {
    if (this.CollectionChanged == null)
      return;
    this.CollectionChanged((object) this, args);
  }

  private void SelectedFaces_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
  {
    this.ValidateIsDataReady();
  }

  public void CreateComponent()
  {
    if (!TxComponent.op_Equality(this.m_component, (ITxObject) null))
      return;
    using (TxLocalComponentCreationData componentCreationData = new TxLocalComponentCreationData())
    {
      componentCreationData.SetAsDisplay();
      this.m_component = TxApplication.ActiveDocument.PhysicalRoot.CreateLocalComponent(componentCreationData);
    }
  }

  private void DestroyComponent(ref TxComponent comp)
  {
    if (!TxComponent.op_Inequality(comp, (ITxObject) null))
      return;
    ((TxBaseGeometryCreationObject) comp).Delete();
    comp = (TxComponent) null;
  }

  public void ResetPreviewMesh()
  {
    foreach (TxMeshComponent txMeshComponent in (Collection<TxMeshComponent>) this.m_blankMeshesWithCoverage)
    {
      if (txMeshComponent.IsValid() && TxMeshComponentEx.HasCoverage(txMeshComponent))
        TxMeshComponentEx.Display(txMeshComponent);
    }
    ((Collection<TxMeshComponent>) this.m_blankMeshesWithCoverage).Clear();
    foreach (ITxObject previewMesh in (Collection<ITxObject>) this.m_previewMeshList)
    {
      Tx2Or3DimensionalGeometryEx.StopFaceEmphasizeByWire(previewMesh as ITx2Or3DimensionalGeometry, this.m_emphasizeColor, (TxColorEmphasizePriority) 1);
      previewMesh.Delete();
    }
    ((Collection<ITxObject>) this.m_previewMeshList).Clear();
    TxApplication.RefreshDisplay();
  }

  public void PreviewMesh()
  {
    this.ResetPreviewMesh();
    try
    {
      this.NewMeshCreated = false;
      int num = 0;
      foreach (ITxObject selectedPart in (Collection<ITxObject>) this.SelectedParts)
      {
        int numPoints = 0;
        if (!this.PreviewMeshForOnePart(selectedPart, out numPoints))
          ++num;
      }
      if (num == 1)
      {
        this.Message = MeshResource.MESH_MESSAGE_MESH_CREATION_FAILED_FOR_SELECTED_PART;
        this.MessageType = MessageTypes.Error;
      }
      else if (num > 1)
      {
        this.Message = string.Format(MeshResource.MESH_MESSAGE_MESH_CREATION_FAILED_FOR_PARTS, (object) num);
        this.MessageType = MessageTypes.Error;
      }
      else
        this.ValidateIsDataReady();
    }
    finally
    {
      TxApplication.RefreshDisplay();
      TxApplication.ActiveUndoManager.ClearAllTransactions();
    }
  }

  public bool ExecuteMesh()
  {
    this.ResetPreviewMesh();
    try
    {
      this.NewMeshCreated = true;
      if (this.DoesAtLeastOneSelectedPartHaveMesh() && this.UserOverwriteRequest() == DialogResult.No)
        this.NewMeshCreated = false;
      if (this.NewMeshCreated)
      {
        foreach (ITxObject selectedPart in (Collection<ITxObject>) this.SelectedParts)
          this.CreateMeshForOnePart(selectedPart);
      }
    }
    finally
    {
      TxApplication.RefreshDisplay();
      TxApplication.ActiveUndoManager.ClearAllTransactions();
    }
    return this.NewMeshCreated;
  }

  private bool DoesAtLeastOneSelectedPartHaveMesh()
  {
    bool flag = false;
    foreach (ITxObject selectedPart in (Collection<ITxObject>) this.SelectedParts)
    {
      if (CUiMeshUtil.DoesPartHaveMesh(selectedPart))
      {
        flag = true;
        break;
      }
    }
    return flag;
  }

  private DialogResult UserOverwriteRequest()
  {
    string meshName = MeshResource.MESH_NAME;
    string overwriteExisting = MeshResource.MESH_OVERWRITE_EXISTING;
    MessageBoxButtons messageBoxButtons = MessageBoxButtons.YesNo;
    MessageBoxIcon messageBoxIcon = MessageBoxIcon.Question;
    return TxMessageBox.Show(overwriteExisting, meshName, messageBoxButtons, messageBoxIcon);
  }

  private bool PreviewMeshForOnePart(ITxObject part, out int numPoints)
  {
    bool flag = false;
    numPoints = 0;
    TxTessallationCreationDataEx tessallationCreationDataEx = new TxTessallationCreationDataEx(part, this.Deviation, this.Distance, this.Angle);
    tessallationCreationDataEx.SetAsDisplay();
    TxObjectList<ITx2Or3DimensionalGeometry> txObjectList = (TxObjectList<ITx2Or3DimensionalGeometry>) null;
    try
    {
      this.CreateComponent();
      txObjectList = TxBaseGeometryCreationObjectEx.CreateTessellation((ITxGeometryCreation) this.Component, tessallationCreationDataEx);
    }
    catch (Exception ex)
    {
    }
    if (txObjectList != null)
    {
      if (part is ITxComponent && TxMeshComponentEx.DoesPartHaveMesh(part as ITxComponent))
      {
        TxMeshComponent mesh = TxMeshComponentEx.GetMesh(part as ITxComponent);
        if (mesh.IsValid() && TxMeshComponentEx.HasCoverage(mesh))
        {
          ((Collection<TxMeshComponent>) this.m_blankMeshesWithCoverage).Add(mesh);
          TxMeshComponentEx.Blank(mesh);
        }
      }
      foreach (ITx2Or3DimensionalGeometry dimensionalGeometry in (Collection<ITx2Or3DimensionalGeometry>) txObjectList)
      {
        ((Collection<ITxObject>) this.m_previewMeshList).Add((ITxObject) dimensionalGeometry);
        Tx2Or3DimensionalGeometryEx.EmphasizeFaceByWire(dimensionalGeometry, this.m_emphasizeColor, (TxColorEmphasizePriority) 3);
      }
      flag = true;
    }
    return flag;
  }

  private bool CreateMeshForOnePart(ITxObject part)
  {
    bool meshForOnePart = false;
    TxTessallationCreationDataEx tessallationCreationDataEx = new TxTessallationCreationDataEx(part, this.Deviation, this.Distance, this.Angle);
    TxMeshComponent txMeshComponent = (TxMeshComponent) null;
    try
    {
      txMeshComponent = TxPhysicalRootEx.CreateMeshComponent(tessallationCreationDataEx);
    }
    catch (Exception ex)
    {
    }
    return meshForOnePart;
  }

  private void ValidateIsDataReady()
  {
    if (((IEnumerable<ITxObject>) this.m_selectedParts).Count<ITxObject>() == 0)
    {
      this.UpdateMessageAndStatus(MeshResource.MESH_MESSAGE_PARTS_ARE_MISSING, MessageTypes.OK, false);
    }
    else
    {
      this.Message = MeshResource.MESH_MESSAGE_READY;
      this.MessageType = MessageTypes.OK;
      this.IsDataReady = true;
    }
  }

  private void UpdateMessageAndStatus(string message, MessageTypes messageType, bool isReady)
  {
    this.m_errorMessage = message;
    this.m_errorMessageType = messageType;
    this.Message = this.m_errorMessage;
    this.MessageType = this.m_errorMessageType;
    this.IsDataReady = isReady;
  }
}
